package com.rgp.internalcommon.utils;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.rgp.internalcommon.common.TokenDurationTimeConstant;
import com.rgp.internalcommon.dto.UserInfoDto;
import java.lang.reflect.Field;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @author nhp
 * @version 1.0
 * @description TODO
 * @date 2024-04-13 0:34
 */
public class JwtUtils {

    private static final String JWT_SECRET = "@#$sl1t9mn";

    public static String tokenGenerate(UserInfoDto userInfoDto, Integer tokenValidTime){

        HashMap<String, Object> map = new HashMap<>();
        map.put("userPhone", userInfoDto.getUserPhone());
        map.put("userName", userInfoDto.getUserName());
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DATE,tokenValidTime);
        Date date = calendar.getTime();

        JWTCreator.Builder builder = JWT.create();
        map.forEach((key,value)->{
            builder.withClaim(key, (String) value);
        });
        builder.withExpiresAt(date);
        String sign = builder.sign(Algorithm.HMAC256(JWT_SECRET));
        return sign;
    }

    public static void main(String[] args) throws Exception {
        UserInfoDto userInfoDto = new UserInfoDto();
        userInfoDto.setUserName("Alex");
        userInfoDto.setUserPhone("15523731049");
        String token = JwtUtils.tokenGenerate(userInfoDto, TokenDurationTimeConstant.ACCESS_TOKEN_VALID_MINUTES);
        System.out.println("token:" + token);
        UserInfoDto infoDto = paseToken(token);
        System.out.println("解析后:" + infoDto);
    }

    public static UserInfoDto paseToken(String token) throws Exception{
        UserInfoDto infoDto = new UserInfoDto();
        Class<? extends UserInfoDto> passengerInfoDtoClass = infoDto.getClass();
        DecodedJWT decodedJWT = JWT.require(Algorithm.HMAC256(JWT_SECRET)).build().verify(token);
        Map<String, Claim> claims = decodedJWT.getClaims();
        claims.forEach((key,value)->{
//            System.out.println(key + ":" + value.asString());
            if (!key.equals("exp")){
                try {
                    Field field = passengerInfoDtoClass.getDeclaredField(key);
                    field.setAccessible(true);
                    field.set(infoDto,value.asString());
                } catch (NoSuchFieldException | IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
        });
        return infoDto;
    }
}
